package com.boot.stomp.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.StompWebSocketEndpointRegistration;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;

import java.util.Arrays;

/**
 * @author 霜寒 <1621856595@qq.com>
 * @description WebSocket 与 Stomp 配置
 * @date 2020/4/27 14:08
 **/
@Slf4j
@EnableWebSocketMessageBroker
@EnableConfigurationProperties(StompProperties.class)
@Configuration
public class StompAutoConfiguration implements WebSocketMessageBrokerConfigurer {

    private final StompProperties stompProperties;

    private ChannelInterceptor[] interceptors;

    private TaskScheduler taskScheduler;

    public StompAutoConfiguration(StompProperties stompProperties) {
        this.stompProperties = stompProperties;
    }

    @Autowired(required = false)
    public void setInterceptors(ChannelInterceptor[] interceptors) {
        this.interceptors = interceptors;
    }

    @Autowired
    @Qualifier("messageBrokerTaskScheduler")
    @Lazy
    public void setTaskScheduler(TaskScheduler taskScheduler) {
        this.taskScheduler = taskScheduler;
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        StompWebSocketEndpointRegistration registration = registry.addEndpoint(stompProperties.getEndpoint())
                .setAllowedOriginPatterns("http://*", "https://*")
                //                .addInterceptors(new SessionHandshakeInterceptor())
                .setHandshakeHandler(new DefaultHandshakeHandler());
        if (stompProperties.getUseSockJs()) {
            registration.withSockJS();
        }
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        //        定义了一个（或多个）客户端订阅地址的前缀信息，也就是客户端接收服务端发送消息的前缀信息
        registry.enableSimpleBroker(stompProperties.getBrokers().toArray(new String[0])).setTaskScheduler(taskScheduler);
        //        定义了服务端接收地址的前缀，也即客户端给服务端发消息的地址前缀
        registry.setApplicationDestinationPrefixes(stompProperties
                .getApplicationDestinationPrefixes().toArray(new String[0]));
        //         点对点使用的订阅前缀（客户端订阅路径上会体现出来），不设置的话，默认也是/user/
        registry.setUserDestinationPrefix(stompProperties.getUserDestinationPrefix());
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        if (interceptors != null) {
            log.debug(Arrays.toString(interceptors));
            registration.interceptors(interceptors);
        }
    }

}
